package cn.lopr.mvc.frame.processors;

import cn.lopr.mvc.frame.base.ParamMapping;
import cn.lopr.mvc.frame.base.RouteValue;
import cn.lopr.util.ArrayUtils;
import com.alibaba.druid.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.sql.SQLException;

public class ParamProcessor extends Processor {

    public Object[] getParam(RouteValue routeValue, HttpServletRequest req) {

        ParamMapping[] paramMappings = routeValue.getParamMappings();

        if (ArrayUtils.isEmpty(paramMappings)) {
            return null;
        }

        // 判断是否需要解析成java bean
        if (routeValue.isRequestBody()) {
            return getRequestBodyParam(routeValue.getMethod(), req);
        }

        Object[] reqParam = new Object[paramMappings.length];
        for (int i = 0; i < paramMappings.length; i++) {
            ParamMapping paramMapping = paramMappings[i];
            String parameter = req.getParameter(paramMapping.getParamName());
            // 取值优先级，表单 > 注解默认值 > session
            if (StringUtils.isEmpty(parameter)) {
                parameter = paramMapping.getDefaultValue();
            } else if (StringUtils.isEmpty(parameter)) {
                parameter = (String) req.getSession().getAttribute(paramMapping.getParamName());
            }

            reqParam[i] = super.processParam(parameter, paramMapping.getParamType());
        }

        return reqParam;
    }

    private Object[] getRequestBodyParam(Method method, HttpServletRequest req) {
        Class<?>[] parameterTypes = method.getParameterTypes();
        PropertyDescriptor[] propertyDescriptors = new PropertyDescriptor[0];
        try {
            propertyDescriptors = propertyDescriptors(parameterTypes[0]);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        Object instance = newInstance(parameterTypes[0]);
        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
            String parameter = req.getParameter(propertyDescriptor.getName());
            if (StringUtils.isEmpty(parameter)) {
                continue;
            }
            Object result = processParam(parameter, propertyDescriptor.getPropertyType());
            callSetter(instance, propertyDescriptor, result);
        }

        return new Object[]{instance};
    }
}
